package trab_sd;

import java.util.*;
import java.net.*;
import java.io.*;

public class UserList extends LinkedList<UserID> implements Serializable
{
	//Tenta adicionar um elemento de identificacao a lista.
	//Caso ja exista esse usuario, retorna false.
	public synchronized boolean add( UserID id )
	{
		//Se a lista estiver vazia, adicina o no.
		if ( isEmpty() )
			return super.add( id );
		
		int i = 0;
		UserID tmp;
		Iterator itr = this.iterator();
		//Verifica a existencia do no.
		while (itr.hasNext())
		{
			i++;
			tmp = (UserID) itr.next();
			//Se ja existir, retorna false.
			if (tmp.equals(id))
				return false;
		}
		//Caso contrario, adicina-o na lista.
		super.add(i, id);
		return true;
	}
	
	// Remove um usuario com o ip fornecido.
	public synchronized void removeByIP(String ip)
	{
		//verifica se a lista esta vazia.
		if ( isEmpty() )
			return;
		
		int i = 0;
		UserID tmp;
		Iterator itr = this.iterator();
		//Percorre a lista em busca do ip.
		while (itr.hasNext())
		{
			i++;
			tmp = (UserID) itr.next();
			if (tmp.getIP().equals(ip))
				break;
		}
		//Caso seja encontrado, remove-o.
		super.remove(i-1);
	}
	
	//Remove um no com o nome fornecido.
	public synchronized void removeByName(String name)
	{
		//verifica se a lista esta vazia
		if ( isEmpty() )
			return;
		
		int i = 0;
		UserID tmp;
		Iterator itr = this.iterator();
		
		//Percorre a lista em busca do nome.
		while (itr.hasNext())
		{
			i++;
			tmp = (UserID) itr.next();
			if (tmp.getName().equals(name))
				break;
		}
		//Remove o no.
		super.remove(i-1);
	}
	
	//Remove um elemento de identificacao.
	/*public synchronized void remove(UserID id)
	{
		//Verifica se a lista esta vazia.
		if ( isEmpty() )
			return;
		
		int i = 0;
		UserID tmp;
		Iterator itr = this.iterator();
		
		//Percorre a lista em busca do usuario fornecido.
		while (itr.hasNext())
		{
			i++;
			tmp = (UserID) itr.next();
			if (tmp.equals(id))
				break;
		}
		//Se o encontrar, remove-o.
		//if (itr.hasNext())
			super.remove(i-1);
	}
	*/
	
	public synchronized void remove(UserID u) {
		if (u == null) return;
		Iterator itr = iterator();
		UserID tmp = null;
		while (itr.hasNext()) {
			tmp = (UserID) itr.next();
			if ( u.equals( tmp ) ) {
				//System.out.println((tmp));
				itr.remove();
			}
		}
	}
	
	//Busca um no pelo seu nome.
	public UserID getByName(String name)
	{
		//Verifica se a lista esta vazia.
		if ( isEmpty() )
			return null;
		
		int i = 0;
		UserID tmp;
		Iterator itr = this.iterator();
		
		//Percorre a lista em busca do nome.
		while (itr.hasNext())
		{
			i++;
			tmp = (UserID) itr.next();
			// Se o no for igual ao procurado, o retorna.
			if (tmp.getName().equals(name))
				return tmp;
		}
		return null;
	}
	
	//Busca um usuario pelo IP. Retorna sua identificacao.
	public UserID getByIP(String ip)
	{
		//Verifica se a lista esta vazia.
		if ( isEmpty() )
			return null;
		
		int i = 0;
		UserID tmp;
		Iterator itr = this.iterator();
		
		//Percorre a lista em busca do IP.
		while (itr.hasNext())
		{
			i++;
			tmp = (UserID) itr.next();
			//Retorna o usuario caso seja encontrado.
			if (tmp.getIP().equals(ip))
				return tmp;
		}
		//Retorna null se nao achar nenhum usuario com o ip.
		return null;
	}
	
	//Retorna um usuario aleatorio.
	public UserID getRandom()
	{
		System.out.println(size());
		Random rndm = new Random();
		return get(Math.abs(rndm.nextInt() % size()));
	}
	
	public String toString()
	{
		Iterator itr = iterator();
		String ret = String.format("%-21s %-10s %-4s\n", "HostName", "IP", "Port");
		UserID tmp;
		
		while (itr.hasNext())
		{
			tmp = (UserID) itr.next();
			ret += tmp.toString() + "\n";
		}
		return ret;
	}
	
}
